package com.gwz.cardserver.consts;

import com.gwz.cardserver.dto.fight.CardDto;

import java.util.List;

public enum CardTypeEnum {
    NONE(0),
    /**
     * 单张
     */
    SINGE(1),
    /**
     * 对儿
     */
    DOUBLE(2),
    /**
     * 顺子
     */
    STRAIGHT(3),
    /**
     * 双顺  44 55 66
     */
    DOUBLE_STRAIGHT(4),
    /**
     * 三顺 444 555 666
     */
    TRIPLE_STRAIGHT(5),
    /**
     * 三不带
     */
    THREE(6),
    /**
     * 三带一
     */
    THREE_ONE(7),
    /**
     * 三带二
     */
    THREE_TWO(8),
    /**
     * 炸弹
     */
    BOOM(9),
    /**
     * 王炸
     */
    JOKER_BOOM(10),
    ;


    private int code;

    CardTypeEnum(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public static CardTypeEnum getByCode(int code) {
        for (CardTypeEnum value : values()) {
            if (value.code == code)
                return value;
        }
        return null;
    }

    /**
     * 是否是单牌
     *
     * @param cardDtos
     * @return
     */
    public static boolean isSingle(List<CardDto> cardDtos) {
        return cardDtos.size() == 1;
    }

    /**
     * 是否是对
     *
     * @param cardDtos
     * @return
     */
    public static boolean isDouble(List<CardDto> cardDtos) {
        if (cardDtos.size() == 2) {
            if (cardDtos.get(0).getWeight() == cardDtos.get(1).getWeight()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否是顺子
     *
     * @param cardDtos
     * @return
     */
    public static boolean isStraight(List<CardDto> cardDtos) {
        if (cardDtos.size() < 5 || cardDtos.size() > 12) {
            return false;
        }
        for (int i = 0; i < cardDtos.size() - 1; i++) {
            int tempWeight = cardDtos.get(i).getWeight();
            if (cardDtos.get(i + 1).getWeight() - tempWeight != 1) {
                return false;
            }
            if (tempWeight > CardWeightEnums.ONE.getCode() || cardDtos.get(i + 1).getWeight() > CardWeightEnums.ONE.getCode()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否是双顺
     *
     * @param cardDtos
     * @return
     */
    public static boolean isDoubleStraight(List<CardDto> cardDtos) {
        if (cardDtos.size() < 6 || cardDtos.size() % 2 != 0) {
            return false;
        }
        for (int i = 0; i < cardDtos.size() - 2; i += 2) {
            if (cardDtos.get(i).getWeight() != cardDtos.get(i + 1).getWeight())
                return false;
            if (cardDtos.get(i + 2).getWeight() - cardDtos.get(i).getWeight() != 1)
                return false;
            if (cardDtos.get(i).getWeight() > CardWeightEnums.ONE.getCode() || cardDtos.get(i + 2).getWeight() > CardWeightEnums.ONE.getCode())
                return false;
        }
        return true;
    }

    /**
     * 是否是飞机
     *
     * @param cardDtos
     * @return
     */
    public static boolean isTripleStraight(List<CardDto> cardDtos) {
        if (cardDtos.size() < 6 || cardDtos.size() % 3 != 0)
            return false;
        for (int i = 0; i < cardDtos.size() - 3; i += 3) {
            if (cardDtos.get(i).getWeight() != cardDtos.get(i + 1).getWeight())
                return false;
            if (cardDtos.get(i + 2).getWeight() != cardDtos.get(i + 1).getWeight())
                return false;
            if (cardDtos.get(i).getWeight() != cardDtos.get(i + 2).getWeight())
                return false;
            if (cardDtos.get(i + 3).getWeight() - cardDtos.get(i).getWeight() != 1)
                return false;
            if (cardDtos.get(i).getWeight() > CardWeightEnums.ONE.getCode() || cardDtos.get(i + 3).getWeight() > CardWeightEnums.ONE.getCode())
                return false;
        }
        return true;
    }

    /**
     * 是否是三不带
     *
     * @param cardDtos
     * @return
     */
    public static boolean isThree(List<CardDto> cardDtos) {
        if (cardDtos.size() != 3)
            return false;
        if (cardDtos.get(0).getWeight() != cardDtos.get(1).getWeight())
            return false;
        if (cardDtos.get(2).getWeight() != cardDtos.get(1).getWeight())
            return false;
        if (cardDtos.get(2).getWeight() != cardDtos.get(0).getWeight())
            return false;
        return true;
    }

    /**
     * 是否是三带一
     *
     * @param cardDtos
     * @return
     */
    public static boolean isThreeAndOne(List<CardDto> cardDtos) {
        if (cardDtos.size() != 4)
            return false;
        if (cardDtos.get(0).getWeight() == cardDtos.get(1).getWeight() && cardDtos.get(1).getWeight() == cardDtos.get(2).getWeight())
            return true;
        if (cardDtos.get(1).getWeight() == cardDtos.get(2).getWeight() && cardDtos.get(2).getWeight() == cardDtos.get(3).getWeight())
            return true;
        return false;
    }

    /**
     * 是否是三带二
     *
     * @param cardDtos
     * @return
     */
    public static boolean isThreeAndTwo(List<CardDto> cardDtos) {
        if (cardDtos.size() != 5)
            return false;
        if (cardDtos.get(0).getWeight() == cardDtos.get(1).getWeight() && cardDtos.get(1).getWeight() == cardDtos.get(2).getWeight()) {
            if (cardDtos.get(3).getWeight() == cardDtos.get(4).getWeight())
                return true;
        }
        if (cardDtos.get(2).getWeight() == cardDtos.get(3).getWeight() && cardDtos.get(3).getWeight() == cardDtos.get(4).getWeight()) {
            if (cardDtos.get(0).getWeight() == cardDtos.get(1).getWeight())
                return true;
        }
        return false;
    }

    /**
     * 判断是否是炸弹
     *
     * @param cardDtos
     * @return
     */
    public static boolean isBoom(List<CardDto> cardDtos) {
        if (cardDtos.size() != 4)
            return false;
        if (cardDtos.get(0).getWeight() != cardDtos.get(1).getWeight())
            return false;
        if (cardDtos.get(1).getWeight() != cardDtos.get(2).getWeight())
            return false;
        if (cardDtos.get(2).getWeight() != cardDtos.get(3).getWeight())
            return false;
        return true;
    }

    /**
     * 判断是否是王炸
     *
     * @param cardDtos
     * @return
     */
    public static boolean isJokerBoom(List<CardDto> cardDtos) {
        if (cardDtos.size() != 2)
            return false;
        if (cardDtos.get(0).getWeight() == CardWeightEnums.SJOKER.getCode() && cardDtos.get(1).getWeight() == CardWeightEnums.LJOKER.getCode())
            return true;
        if (cardDtos.get(0).getWeight() == CardWeightEnums.LJOKER.getCode() && cardDtos.get(1).getWeight() == CardWeightEnums.SJOKER.getCode())
            return true;
        return false;
    }

    /**
     * 获取卡牌类型
     *
     * @param cardDtos
     * @return
     */
    public static int getCardType(List<CardDto> cardDtos) {
        int cardType = CardTypeEnum.NONE.getCode();
        switch (cardDtos.size()) {
            case 1: {
                if (isSingle(cardDtos)) {
                    cardType = CardTypeEnum.SINGE.getCode();
                }
                break;
            }
            case 2: {
                if (isDouble(cardDtos)) {
                    cardType = CardTypeEnum.DOUBLE.getCode();
                } else if (isJokerBoom(cardDtos)) {
                    cardType = CardTypeEnum.JOKER_BOOM.getCode();
                }
                break;
            }
            case 3: {
                if (isThree(cardDtos)) {
                    cardType = CardTypeEnum.THREE.getCode();
                }
                break;
            }
            case 4: {
                if (isBoom(cardDtos)) {
                    cardType = CardTypeEnum.BOOM.getCode();
                } else if (isThreeAndOne(cardDtos)) {
                    cardType = CardTypeEnum.THREE_ONE.getCode();
                }
                break;
            }
            case 5: {
                if (isStraight(cardDtos)) {
                    cardType = CardTypeEnum.STRAIGHT.getCode();
                } else if (isThreeAndTwo(cardDtos)) {
                    cardType = CardTypeEnum.THREE_TWO.getCode();
                }
                break;
            }
            case 6:
            case 12: {
                if (isStraight(cardDtos)) {
                    cardType = CardTypeEnum.STRAIGHT.getCode();
                } else if (isDoubleStraight(cardDtos)) {
                    cardType = CardTypeEnum.DOUBLE_STRAIGHT.getCode();
                } else if (isTripleStraight(cardDtos)) {
                    cardType = CardTypeEnum.TRIPLE_STRAIGHT.getCode();
                }
                break;
            }
            case 7:
            case 11: {
                if (isStraight(cardDtos)) {
                    cardType = CardTypeEnum.STRAIGHT.getCode();
                }
                break;
            }
            case 8:
            case 10: {
                if (isStraight(cardDtos)) {
                    cardType = CardTypeEnum.STRAIGHT.getCode();
                } else if (isDoubleStraight(cardDtos)) {
                    cardType = CardTypeEnum.DOUBLE_STRAIGHT.getCode();
                }
                break;
            }
            case 9: {
                if (isStraight(cardDtos)) {
                    cardType = CardTypeEnum.STRAIGHT.getCode();
                } else if (isTripleStraight(cardDtos)) {
                    cardType = CardTypeEnum.TRIPLE_STRAIGHT.getCode();
                }
                break;
            }
            case 14:
            case 16:
            case 20:
                {
                if (isDoubleStraight(cardDtos)) {
                    cardType = CardTypeEnum.DOUBLE_STRAIGHT.getCode();
                }
                break;
            }
            case 15: {
                if (isTripleStraight(cardDtos)) {
                    cardType = CardTypeEnum.TRIPLE_STRAIGHT.getCode();
                }
                break;
            }
            case 18: {
                if (isDoubleStraight(cardDtos)) {
                    cardType = CardTypeEnum.DOUBLE_STRAIGHT.getCode();
                } else if (isTripleStraight(cardDtos)) {
                    cardType = CardTypeEnum.TRIPLE_STRAIGHT.getCode();
                }
                break;
            }


        }
        return cardType;
    }
}
